#ifndef GAME_H
#define GAME_H

#include <QObject>
#include <QNetworkAccessManager>
#include "GameCommon.h"
#include "Round.h"
#include "GameSetting.h"
#include "ScoreSheet.h"
#include <QMap>

class Game : public QObject
{    
    Q_PROPERTY(int playerNumber READ playerNumber)

    Q_PROPERTY(GameStage stage READ stage)


    Q_ENUMS(GameStage)
    Q_OBJECT
public:
    explicit Game(QObject *parent = nullptr);


    enum GameStage{
        Stoped  = 0,
        Started,
        PlayerReady,
        Competing,
        Answering,
        Answered
    };

    GameStage  stage() const;

    Q_INVOKABLE QString question() const;
    Q_INVOKABLE int     optionNumber() const;
    Q_INVOKABLE QString optionAt(int index) const;
    Q_INVOKABLE int     rightSelectionIndex() const;

    Q_INVOKABLE bool    hasNextRound() const;

    Q_INVOKABLE bool    needNextPlayer() const;

    Q_INVOKABLE  GameSetting*  setting();

    Q_INVOKABLE int correctNumberOf(quint32 playerId) const;
    Q_INVOKABLE int incorrectNumberOf(quint32 playerId) const;
    Q_INVOKABLE int scoreOf(quint32 playerId) const;

    Q_INVOKABLE int  selection() const;
    Q_INVOKABLE bool isCorrect() const;


    int playerNumber() const;
    Q_INVOKABLE quint32 playerIdAt(int index);


    Q_INVOKABLE void setGameSetting(GameSetting * setting);


    bool loadRoundFromDatabase();
    Q_INVOKABLE bool loadSetting();
    Q_INVOKABLE bool saveSetting();


signals:

    void  competitorLocked(quint32 player);
    void  validSelectionCommited(quint32 player, int selection);
    void  playerJoin(quint32 player);
    void  playerIllegal(quint32 player);
    void  allPlayerReady();


    // 要求指定下位机读取手环码
    void  askToReadBracelet(quint32 playerMask);

    // 要求所有下位机复位
    void  askToReset();

    // 通知所有下位机开始抢答
    void  askToCompete();

public slots:
    void beginGame();
    void endGame();
    void pushScore();

    void roundNext();

    void readBracelet(quint32 player);

    void beginCompete();

    void endCompete();


    void validateCompetitor(quint32 player);
    void validateSelection(quint32 player, int selection);

    // 从服务器获取手环码对应的学生ID
    void validatePlayer(quint32 player,  QByteArray braceletSn);

    void fakePlayer(quint32 player, QByteArray braceletSn);

    void  onStudentRequestSuccess(const QString braceletSn,  qint64 studentId);
    void  onStudentRequestFail(int error, const QString errorString);


private:

    GameStage               m_currStage;

    QVector<Round>          m_allRound;


    int                     m_currRoundCursor;
    QVector<Round>          m_gameRounds;
    void generateGameRound();


    GameSetting             m_setting;


    QList<qint64>           m_students;


    quint32                  m_lead;
    int                      m_leadSelection;



    unsigned char* m_flags;



    QVector<ScoreCell>  m_sheet;
    void decision();


    QString m_hardwareId;

};

#endif // GAME_H
